#-*- encoding:gbk -*-
import pysvn
import os.path
import os
import shutil
import sys
import stat

class SvnClient():
    
    def __init__(self, url, path, username, password):
        
        self.URL = url
        self.PATH = path
        self.USERNAME = username
        self.PASSWORD = password
        
        self.client = pysvn.Client()
        self.client.callback_get_login = self.get_login

        
    def checkout(self):
        
        self.client.checkout(self.URL, self.PATH)
    
    def checkin(self, file):
        
        self.client.checkin(file, 'test')
        
    def update(self):
        
        self.client.update(self.PATH)

    def get_login( self, realm, username, may_save ):
              
        return 1, self.USERNAME, self.PASSWORD, 1
  
    def add(self, file):
        
        self.client.add(file)
        self.client.checkin(self.PATH, 'test')
    
    def delete(self, file):
        
        self.client.remove(file)
        self.client.checkin(self.PATH, 'test')
        
    def import_(self):
        
        self.client.import_(self.PATH, self.URL, 'test')
    
    #delete .svn directory
    def deleteSubFile(self, svnpath):
        names = os.listdir(svnpath)
        for name in names:
            
            fp = os.path.join( svnpath, name)
            if (os.path.isfile(fp)):
                os.chmod( fp, stat.S_IWRITE)
                os.remove(fp)
            else:
                self.deleteSubFile(fp)
                
    #delete .svn directory
    def deleteSVN(self, parentPath = None, dir = None):
        if (dir != None and dir == '.svn'):
            self.deleteSubFile(os.path.join( parentPath, dir))
            shutil.rmtree(os.path.join( parentPath, dir), True, False)
            #print 'deleted ', os.path.join( parentPath, dir)
        else:
            if (dir != None):
                filePath = os.path.join( parentPath, dir)
            else:
                filePath = parentPath
            names = os.listdir(filePath)
            for name in names:
                fp = os.path.join( filePath, name)
                if (os.path.isdir(fp)):
                    self.deleteSVN(filePath, name)  
    
    def  check(self):
        
        changes           = self.client.status(self.PATH)
        missing_list_file = []
        missing_list_dir  = []
        missing_list      = []
        unversioned_list  = []
        deleted_list      = []
        modified_list     = []
        
        for f in changes:
                      
            if f.text_status == pysvn.wc_status_kind.normal:
                continue
            
            elif f.text_status == pysvn.wc_status_kind.missing:
                
                if os.path.isfile(f.path):
                    missing_list_file.append(f)
                elif os.path.isdir(f.path):
                    missing_list_dir.append(f)
                else:
                    missing_list.append(f)
                              
            elif f.text_status == pysvn.wc_status_kind.unversioned: 
                unversioned_list.append(f) 
            
            elif f.text_status == pysvn.wc_status_kind.deleted:
                deleted_list.append(f) 
            
            elif f.text_status == pysvn.wc_status_kind.modified: 
                modified_list.append(f)                       
            
        #delete the file and directory which has been deleted in local file system
        for f in missing_list_file:
            self.delete(f.path)
        
        for f in missing_list_dir:
            self.delete(f.path)
        
        for f in missing_list:
            self.delete(f.path)
        
        #add the new file and directory which moved into the local rep
        for f in unversioned_list:            
            
            if os.path.isdir(f.path):   
                self.deleteSVN(f.path)
            
            self.add(f.path)        
       
        #delete the file and directory which has been signed for being deleted
        for f in deleted_list:
            self.delete(f.path)
            
        #checkin the file which has been changed
        for f in modified_list:
             self.checkin(f.path)

            
        
         